#include <stdlib.h>
#include <stdio.h>
#include "bzrc.h"
#include "bzrc_test.h"

#define IP_ADDRESS "127.0.0.1"
extern int debug;

int main(int argc, char* argv[]) {
	int tcpSocket = 0;
	FILE* fSocket = 0;
	if (argc < 2) {
		fprintf(stderr, "usage: bzrc port [debug 1:0]\n");
		exit(-1);
	}
	if (argc == 3 && atoi(argv[2]) == 1) {
		debug = 1;
	}


	BZRCConnect(IP_ADDRESS, atoi(argv[1]), &tcpSocket, &fSocket);
	setSpeed(fSocket, 0, 0);
	setAngVel(fSocket, 0, -0.5);
	shoot(fSocket, 0);
	shoot(fSocket, 0); // This should fail (shooting before reload)
	printTeams(fSocket);
	printObstacles(fSocket);
	printBases(fSocket);
	printFlags(fSocket);
	printShots(fSocket);
	printMyTanks(fSocket);
	printOtherTanks(fSocket);
	printConstants(fSocket);
	printOccGrid(fSocket, 0);
	BZRCDisconnect(tcpSocket, fSocket);


	return 0;
}

void printTeams(FILE* fSocket) {
	team* teams;
	int teamCount;
	int i;
	getTeams(fSocket, &teams, &teamCount);
	for (i = 0; i < teamCount; i++) {
		printf("Team: %s, Players: %d\n", teams[i].color, teams[i].playerCount);
	}
	free(teams);
	return;
}

void printObstacles(FILE* fSocket) {
	obstacle* obstacles;
	int obstacleCount;
	int i;
	getObstacles(fSocket, &obstacles, &obstacleCount);
	for (i = 0; i < obstacleCount; i++) {
		printf("Obstacle: (%02.1f,%02.1f) (%02.1f,%02.1f) (%02.1f,%02.1f) (%02.1f,%02.1f)\n", 
			obstacles[i].corners[0].x,
			obstacles[i].corners[0].y,
			obstacles[i].corners[1].x,
			obstacles[i].corners[1].y,
			obstacles[i].corners[2].x,
			obstacles[i].corners[2].y,
			obstacles[i].corners[3].x,
			obstacles[i].corners[3].y
		);
	}
	free(obstacles);
	return;
}

void printBases(FILE* fSocket) {
	base* bases;
	int baseCount;
	int i;
	getBases(fSocket, &bases, &baseCount);
	for (i = 0; i < baseCount; i++) {
		printf("Base: [%s] (%02.1f,%02.1f) (%02.1f,%02.1f) (%02.1f,%02.1f) (%02.1f,%02.1f)\n", 
			bases[i].color,
			bases[i].corners[0].x,
			bases[i].corners[0].y,
			bases[i].corners[1].x,
			bases[i].corners[1].y,
			bases[i].corners[2].x,
			bases[i].corners[2].y,
			bases[i].corners[3].x,
			bases[i].corners[3].y
		);
	}
	free(bases);
	return;
}

void printFlags(FILE* fSocket) {
	flag* flags;
	int flagCount;
	int i;
	getFlags(fSocket, &flags, &flagCount);
	for (i = 0; i < flagCount; i++) {
		printf("Flag: %s's flag held by %s at (%02.1f,%02.1f)\n", 
			flags[i].ownerColor,
			flags[i].holderColor,
			flags[i].location.x,
			flags[i].location.y
		);
	}
	free(flags);
	return;
}

void printShots(FILE* fSocket) {
	shot* shots;
	int shotCount;
	int i;
	getShots(fSocket, &shots, &shotCount);
	for (i = 0; i < shotCount; i++) {
		printf("Shot: At (%02.1f,%02.1f) with velocity (%02.1f,%02.1f)\n", 
			shots[i].location.x,
			shots[i].location.y,
			shots[i].velocity.x,
			shots[i].velocity.y
		);
	}
	free(shots);
	return;
}

void printMyTanks(FILE* fSocket) {
	tank* tanks;
	int tankCount;
	int i;
	getMyTanks(fSocket, &tanks, &tankCount);
	for (i = 0; i < tankCount; i++) {
		printf("Tank %d: %s is %s with %d shots and %f seconds before reload\n", 
			tanks[i].index,
			tanks[i].callsign,
			tanks[i].status,
			tanks[i].shotsAvailble,
			tanks[i].reloadTime
		);
	}
	free(tanks);
	return;
}

void printOtherTanks(FILE* fSocket) {
	enemyTank* tanks;
	int tankCount;
	int i;
	getOtherTanks(fSocket, &tanks, &tankCount);
	for (i = 0; i < tankCount; i++) {
		printf("Tank %s is %s and located at (%02.1f, %02.1f)\n", 
			tanks[i].callsign,
			tanks[i].status,
			tanks[i].location.x,
			tanks[i].location.y
		);
	}
	free(tanks);
	return;
}

void printConstants(FILE* fSocket) {
	constant* constants;
	int constantCount;
	int i;
	getConstants(fSocket, &constants, &constantCount);
	for (i = 0; i < constantCount; i++) {
		printf("Constant: %s = %s\n", 
			constants[i].name,
			constants[i].value
		);
	}
	free(constants);
	return;
}

void printOccGrid(FILE* fSocket, int entID) {
	occgrid grid;
	if (getOccGrid(fSocket, &grid, entID)) {
		printf("Failed to get occgrid for tank: %d\n", entID);
		return;
	}
	int i;
	int j;
	printf("Occ Grid for tank %d is at (%02.0f,%02.0f) of size (%02.0f,%02.0f)\n", 
		entID, grid.topleft.x, grid.topleft.y, grid.size.x, grid.size.y);
	for (i = 0; i < grid.size.x; i++) {
		for (j = 0; j < grid.size.y; j++) {
			printf("%c ", grid.grid[i * (int)grid.size.y + j]);
		}
		printf("\n");
	}
	free(grid.grid);
	return;
}

